using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using CyberOPCClient;

using CyberOPCSpecification;

namespace SampleClient
{
    public partial class Main : Form
    {
        // Define the CyberOPC Object Client Library
        private CyberOPCClient.CyberOPCClient CybCli;
        // The File log
        private string FileLogDir;
        

        public Main()
        {
            InitializeComponent();
            Init();
        }

        public void Init()
        {
            // Initialize an instance of the CyberOPC Client class
            CybCli = new CyberOPCClient.CyberOPCClient();
            // Set the HTTP method to POST(Default value)
            CybCli.HttpMethod = "POST";
            // Register to the CyberOPC event for log notifications 
            CybCli.LogChange += new CyberOPCClient.CyberOPCClient.LogEventHandler(this.ReceivedLog_Event);
            // Register to the CyberOPC event for data change
            CybCli.DataChange += new CyberOPCClient.CyberOPCClient.DataChangeEventHandler(this.ReceivedData_Event);
            // Set StreamBufferSize
            CybCli.BufferSize = 10000;
        }

      
        #region Event Log 

        private void ReceivedLog_Event(object sender, CyberOPCClient.CyberOPCClient.LogEventArgs e)
        {
            UpdateLOGDo(e._Logline);
        }
        
        private delegate void UpdateLOGDelegate(string logline);
       
        private void UpdateLOGDo(string logline)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new UpdateLOGDelegate(UpdateLOGDo), new object[] { logline });

                return;
            }
            this.richTextBox1.AppendText(">"+logline + "\r\n");
            this.richTextBox1.Focus();
            this.richTextBox1.SelectionStart = richTextBox1.Text.Length - 1;
            this.richTextBox1.ScrollToCaret();
            //Application.DoEvents();
        }

        #endregion

        #region Event DataChange

        private void ReceivedData_Event(object sender, CyberOPCClient.CyberOPCClient.DataChangeEventArgs e)
        {
            UpdateGUIDo(e._ItemsChanged);
        }


        private delegate void UpdateGUIDelegate(ReadResponse.RItem[] ItemsChanged);

        private void UpdateGUIDo(ReadResponse.RItem[] ItemsChanged)
        {
            if (this.InvokeRequired)
            {
                this.BeginInvoke(new UpdateGUIDelegate(UpdateGUIDo), new object[] { ItemsChanged });

                return;
            }
            lv.BeginUpdate();
            // Find and Replace or Add New
            foreach (ReadResponse.RItem item in ItemsChanged)
            {
                if (lv.Items.ContainsKey(item.ItemID))
                {
                    lv.Items[item.ItemID].SubItems[1].Text = item.Value;
                    lv.Items[item.ItemID].SubItems[2].Text = item.Timestamp;
                }
                else
                { 
                    ListViewItem lvi = new ListViewItem();
                    lvi.Name = item.ItemID;
                    lvi.Text = item.ItemID;
                    ListViewItem.ListViewSubItem lvsi1 = new ListViewItem.ListViewSubItem();
                    lvsi1.Text = item.Value;
                    lvi.SubItems.Add(lvsi1);
                    ListViewItem.ListViewSubItem lvsi2 = new ListViewItem.ListViewSubItem();
                    lvsi2.Text = item.Timestamp;
                    lvi.SubItems.Add(lvsi2);
                    lv.Items.Add(lvi);
                }
            }
            lv.EndUpdate();
            pgbar.Value = CybCli.BufferCount;
            pgbar.Refresh();
            int percent = (int)(((double)pgbar.Value / (double)pgbar.Maximum) * 100);
            pgbar.CreateGraphics().DrawString(percent.ToString() + "% buffer", new Font("Arial", (float)8, FontStyle.Regular), Brushes.Black, new PointF(pgbar.Width / 2 - 10, pgbar.Height / 2 - 7));
        }

        #endregion

        #region GUI Private Methods

        private void Main_Load(object sender, EventArgs e)
        {
           this.ActiveControl = this.txtIPServer;
           this.pgbar.Maximum = CybCli.BufferSize;
          
        }

        // Set the Folder Path for the datalog file
        private void btDialog_Click(object sender, EventArgs e)
        {
            if (flg.ShowDialog() == DialogResult.OK)
            {
                this.FileLogDir = flg.SelectedPath.ToString();
            }
            this.txtPathFileLog.Text = this.FileLogDir;
        }
        #endregion

        
        private void btGetStatus_Click(object sender, EventArgs e)
        {
              GetStatusResponse GetStatusResponse = CybCli.GetStatus();
              richTextBox1.AppendText(String.Format(
                  ">ReceiceTime: {0}\r\n>ReplyTime: {1}\r\n>ServerState: {2}\r\n>StartTime: {3}\r\n>ProductVersion: {4}\r\n>VendorInfo: {5}\r\n>Specification: {6}\r\n",
                  GetStatusResponse.getstatusresult.RcvTime,
                  GetStatusResponse.getstatusresult.ReplyTime,
                  GetStatusResponse.getstatusresult.ServerState,
                  GetStatusResponse.statusinfo.StartTime,
                  GetStatusResponse.statusinfo.ProductVersion,
                  GetStatusResponse.vendorinfo,
                  GetStatusResponse.specification ));
              richTextBox1.Focus();
              richTextBox1.SelectionStart = richTextBox1.Text.Length - 1;
              richTextBox1.ScrollToCaret(); 
        }

        private void rbGET_CheckedChanged(object sender, EventArgs e)
        {
            if (rbGET.Checked) CybCli.HttpMethod = "GET";
            else CybCli.HttpMethod = "POST";
        }

        private void btBrowse_Click(object sender, EventArgs e)
        {
            //string ItemPath = CybCli
        }

        private void btRead_Click(object sender, EventArgs e)
        {
            ReadResponse ReadResponse = CybCli.Read(new ReadRequest((string[])txtRead.Text.Split(',')));
            richTextBox1.AppendText(String.Format(
                ">ReceiceTime: {0}\r\n>ReplyTime: {1}\r\n>ServerState: {2}\r\n",
                ReadResponse.readresult.RcvTime,
                ReadResponse.readresult.ReplyTime,
                ReadResponse.readresult.ServerState));
            foreach (ReadResponse.RItem ritem in ReadResponse.ritemlist)
            {
                richTextBox1.AppendText(String.Format(
                    "  >ItemID: {0}\r\n  >TimeStamp: {1}\r\n  >Value: {2}\r\n",
                    ritem.ItemID,
                    ritem.Timestamp,
                    ritem.Value ));
            }
            richTextBox1.Focus();
            richTextBox1.SelectionStart = richTextBox1.Text.Length - 1;
            richTextBox1.ScrollToCaret(); 
        }

        private void btWrite_Click(object sender, EventArgs e)
        {
            //WriteResponse WriteResponse = CybCli.Write(new WItemList { { ItemID, Value } });
            //WriteResponse.ToString();
        }

        private void btReadEDD_Click(object sender, EventArgs e)
        {
            ReadEDDResponse ReadEDDResponse = CybCli.ReadEDD(new ReadEDDRequest(txtReadEDD.Text.Split('.')[0], txtReadEDD.Text.Split('.')[1]));
            richTextBox1.AppendText(String.Format(
                ">ReceiceTime: {0}\r\n>ReplyTime: {1}\r\n>ServerState: {2}\r\n",
                ReadEDDResponse.readresult.RcvTime,
                ReadEDDResponse.readresult.ReplyTime,
                ReadEDDResponse.readresult.ServerState));
            richTextBox1.AppendText(String.Format(
                    "  >EDDfile: {0}\r\n  >EDDfileURL: {1}\r\n",
                    ReadEDDResponse.eddfilename,
                    ReadEDDResponse.eddfileurl));
            richTextBox1.Focus();
            richTextBox1.SelectionStart = richTextBox1.Text.Length - 1;
            richTextBox1.ScrollToCaret(); 
        }

        private void btReadEDDTable_Click(object sender, EventArgs e)
        {
            ReadEDDTableResponse ReadEDDTableResponse = CybCli.ReadEDDTable();
            richTextBox1.AppendText(String.Format(
               ">ReceiceTime: {0}\r\n>ReplyTime: {1}\r\n>ServerState: {2}\r\n",
               ReadEDDTableResponse.readresult.RcvTime,
               ReadEDDTableResponse.readresult.ReplyTime,
               ReadEDDTableResponse.readresult.ServerState));
            foreach (var pair in ReadEDDTableResponse.eddtable)
            {
               richTextBox1.AppendText(String.Format(
                    "  >ModuleName.DeviceID: {0}\r\n  >EDDfile: {1}\r\n  >Value: {2}\r\n",
                    pair.Key,
                    pair.Value));
            }
            richTextBox1.Focus();
            richTextBox1.SelectionStart = richTextBox1.Text.Length - 1;
            richTextBox1.ScrollToCaret(); 
        }

        private void btStreamSubscribe_Click(object sender, EventArgs e)
        {
            StreamSubscriptionResponse streamsubscriptionresponse = CybCli.StreamSubscriptionRequest(new StreamSubscriptionRequest((string[])txtStreamSubscribe.Text.Split(',')));
            richTextBox1.AppendText(String.Format(
                ">ReceiceTime: {0}\r\n>ReplyTime: {1}\r\n>ServerState: {2}\r\n",
                streamsubscriptionresponse.streamresult.RcvTime,
                streamsubscriptionresponse.streamresult.ReplyTime,
                streamsubscriptionresponse.streamresult.ServerState));
            foreach (string ritem in streamsubscriptionresponse.itemlist)
            {
                richTextBox1.AppendText(String.Format(">ItemID: {0}\r\n",ritem ));
            }
            richTextBox1.AppendText(String.Format(">ServerHandle: {0}\r\n ",streamsubscriptionresponse.serverhandle.ToString()));
            richTextBox1.Focus();
            richTextBox1.SelectionStart = richTextBox1.Text.Length - 1;
            richTextBox1.ScrollToCaret(); 
        }

        private void btStreamStart_Click(object sender, EventArgs e)
        {
            // Set the basic CyberOPC Connection Properties 
            CybCli.machineName = txtIPServer.Text;
            CybCli.certificateName = txtCertificateName.Text;
            CybCli.port = Int32.Parse(txtPort.Text);
            decimal DeadBand = numericUpDownDeadBand.Value;
            Int32 ServerHandle = Int32.Parse(txtSeverHandle.Text);
            Int32 WaitTime = (Int32)numericUpDownWaitTime.Value;
            if (rbPOST.Checked) CybCli.HttpMethod = "POST";
            else CybCli.HttpMethod = "GET";
            if (txtPathFileLog.Text.Length != 0)
            {
                CybCli.LogFile = txtPathFileLog.Text + "\\" + "CyberOPC_Cli.txt";
            }
            CybCli.StartStream(ServerHandle, DeadBand, WaitTime);
     
        }

        private void txtIPServer_TextChanged(object sender, EventArgs e)
        {
            CybCli.machineName = txtIPServer.Text;
        }

        private void txtCertificateName_TextChanged(object sender, EventArgs e)
        {
            CybCli.certificateName = txtCertificateName.Text;
        }

        private void txtPort_TextChanged(object sender, EventArgs e)
        {
            CybCli.port = Int32.Parse(txtPort.Text);
        }

        private void txtPathFileLog_Leave(object sender, EventArgs e)
        {
            MessageBox.Show("Enabling this field the streaming messages\nwill not displayed below and will be\nredirected to the text log file.", "Sample Client", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void btStreamUnSubscribe_Click(object sender, EventArgs e)
         {

             StreamCancelResponse streamcancelresponse = CybCli.StreamSubscriptionCancel(new StreamSubscriptionCancel(Int32.Parse(txtSeverHandle.Text)));
             richTextBox1.AppendText(String.Format(
                 ">ReceiceTime: {0}\r\n>ReplyTime: {1}\r\n>ServerState: {2}\r\n",
                 streamcancelresponse.streamresult.RcvTime,
                 streamcancelresponse.streamresult.ReplyTime,
                 streamcancelresponse.streamresult.ServerState));

             richTextBox1.AppendText(String.Format(">ServerHandle: {0}\r\n ", streamcancelresponse.serverhandle.ToString()));
             richTextBox1.Focus();
             richTextBox1.SelectionStart = richTextBox1.Text.Length - 1;
             richTextBox1.ScrollToCaret(); 
     
         }

        private void btStreamStop_Click(object sender, EventArgs e)
        {
            string StrHandle = CybCli.StopStream(Int32.Parse(txtSeverHandle.Text));
            richTextBox1.AppendText(String.Format(">Stopped Stream with ServerHandle: {0}\r\n ", StrHandle));
            richTextBox1.Focus();
            richTextBox1.SelectionStart = richTextBox1.Text.Length - 1;
            richTextBox1.ScrollToCaret(); 
            
        }

       

    }
}